package yc.tool.dbmigrate.dao;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.StringUtils;

import yc.tool.dbmigrate.common.Constant;
import yc.tool.dbmigrate.entity.FieldInfo;
import yc.tool.dbmigrate.entity.TableInfo;
import yc.tool.dbmigrate.exception.DbException;
import yc.tool.dbmigrate.exception.SyncConfigException;

public abstract class AbstractCommonDao implements ICommonDao {
	
	private final Logger log = LoggerFactory.getLogger(this.getClass());
	
	protected JdbcTemplate jdbcTemplate_source;
	protected JdbcTemplate jdbcTemplate_tag;

	@Override
	public Integer tableSize(TableInfo tableInfo) throws Exception {
		StringBuffer sb = new StringBuffer();
		sb.append("select count(*) from ");
		sb.append(tableInfo.getSourceTableName());
		
		StringBuffer whereSb = new StringBuffer();
		List<FieldInfo> fieldInfos = tableInfo.getFieldInfos();
		for (FieldInfo fieldInfo : fieldInfos) {
			if (!StringUtils.isEmpty(fieldInfo.getSourceWhere())) {
				whereSb.append(" ");
				whereSb.append(fieldInfo.getSourceFieldName());
				whereSb.append(fieldInfo.getSourceWhere().getShortSql());
			}
		}
		if (whereSb.length() > 0) {
			sb.append(" where ");
			sb.append(whereSb);
		}
		
		String sql = sb.toString();
		log.info("countSql:" + sql);
		
		return jdbcTemplate_source.queryForObject(sql, Integer.class);
	}

	@Override
	public void insertDataBat(TableInfo tableInfo, List<Map<String, Object>> data, String sourceDbType) throws Exception {
		BatchPreparedStatementSetter bps = new BatchPreparedStatementSetter() {

			@Override
			public void setValues(PreparedStatement ps, int i) throws SQLException {
				Map<String, Object> itemData = data.get(i);
				try {
					switch(sourceDbType) {
					case Constant.DBTYPE_SQLSERVER:
						handleParamsForInsertFromSqlserver(ps, itemData, tableInfo);
						break;
					case Constant.DBTYPE_ORACLE:
						handleParamsForInsertFromOracle(ps, itemData, tableInfo);
						break;
					case Constant.DBTYPE_MYSQL:
						handleParamsForInsertFromMysql(ps, itemData, tableInfo);
						break;
					default:
						throw new SyncConfigException("源数据库类型配置不支持");
					}
					
				} catch (Exception e) {
					throw new DbException("为插入操作设置参数异常");
				}
			}

			@Override
			public int getBatchSize() {
				return data.size();
			}
			
		};
		
		String sql = getInsertSqlTemplate(tableInfo);
		jdbcTemplate_tag.batchUpdate(sql, bps);
		
	}

	@Override
	public String getInsertSqlTemplate(TableInfo tableInfo) throws Exception {
		StringBuffer sb = new StringBuffer();
		sb.append("insert into ");
		sb.append(tableInfo.getTagTableName());
		sb.append("(");
		
		List<FieldInfo> fields = tableInfo.getFieldInfos();
		for (int i = 0; i < fields.size(); i++) {
			sb.append(handleKeyWordInSql(fields.get(i).getTagFieldName()));
			if (i < (fields.size() - 1)) {
				sb.append(", ");
			}
		}
		
		sb.append(") values(");
		for (int i = 0; i < fields.size(); i++) {
			sb.append("?");
			if (i < (fields.size() - 1)) {
				sb.append(", ");
			}
		}
		sb.append(")");
		
		return sb.toString();
	}
	
	
}
